package dialogs.player;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Locale;

import javax.swing.JOptionPane;
import javax.swing.event.TableModelEvent;
//import javax.swing.table.TableModel;

import com.db4o.ObjectContainer;
import com.db4o.ObjectSet;

import persistence.Player;
import dialogs.ChildController;

/**
 * Die Klasse PlayerController erweitert die Klasse ChildController und
 * implementiert das Interface ChildController
 *
 */
public class PlayerController extends ChildController
implements ActionListener  {

	private PlayerView  view;
	
	// Modell, fuer das Eingabe-Formular
	private PlayerInputModel inputModel;
	
	// Modell fuer die Spielerliste
	private PlayerTableModel tableModel;
	
	// Datenbank-Handle
	private ObjectContainer db;
	
	/**
	 * 
	 * @param db Datenbank-Handle
	 * 
	 */
	public PlayerController(ObjectContainer db) {
		this.db = db;
		// neues PlayerModel anlegen
		inputModel = new PlayerInputModel();
		setTableModel(new PlayerTableModel());
		
		ArrayList<Player> players = new ArrayList<Player>();
        ObjectSet<Player> result = db.queryByExample( Player.class );
		for (Player p : result){
			players.add( p );
		}
		// Liste von Spielern setzen
		getTableModel().setPlayers(players);
		// Neue View erzeugen
		view =  new PlayerView(inputModel, getTableModel());
		// Anmelden an der View als ActionListener, damit der Controller
		// ueber Events von der View (z.B. Button-Clicks) informiert wird
		view.addActionListener(this);
	}

	/**
	 * Methode um auf Events (z.B aus der View) zu reagieren
	 * @param ae ActionEvent
	 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
	 */
	@Override
	public void actionPerformed(ActionEvent ae) {
		
		switch (ae.getActionCommand()) {
		case "add":
			addPlayer();
			break;
		case "edit":
			editPlayer();
			break;
		case "deactivate":
			deactivatePlayer();
			break;
		case "load":
			loadPlayer();
			break;
		case "togglefilter":
			toggleFilter();
			break;
		}		
	}
	/**
	 * Versucht einen in der Tabelle angeklickten Spieler mit den angegebenen werten zu aendern
	 */
	private void editPlayer() {
		// TODO 
		int playerIndex = view.getSelectedPlayerIndex();
		if (playerIndex != -1) {
		Player player = getTableModel().getPlayerAt(playerIndex);
		
		inputModel.setFirstName(view.getFirstNameText());
		inputModel.setFamilyName(view.getFamilyNameText());
		inputModel.setPlaysSince(view.getPlaysSinceText());
		inputModel.setDateOfBirth(view.getDobText());
		
		if(inputModel.isModelValid() == false) {
			
			JOptionPane.showMessageDialog(view,
				    "Eingabe ist noch fehlerhaft.",
				    "Fehler",
				    JOptionPane.ERROR_MESSAGE);
		}
		else {
			player.setFirstName(inputModel.getFirstName());
			player.setFamilyName(inputModel.getFamilyName());
			player.setPlaysSince(inputModel.getPlaysSince());
			player.setDateOfBirth(inputModel.getDateOfBirth());
			
			db.store(player);
			// Loeschen der alten Textfeldinhalte
			view.refresh();
			System.out.println("Player stored");
			// Benachrichtigen des MainControllers
			this.setChanged();
			this.notifyObservers();
			getTableModel().fireTableChanged(new TableModelEvent(getTableModel()));
		}
		} else {
			System.err.println("No Player selected!");
			JOptionPane.showMessageDialog(view,
				    "Sie haben keinen Spieler ausgewählt!",
				    "Fehler",
				    JOptionPane.ERROR_MESSAGE);
		}
	}
	
	/**
	 * deactiviert den ausgewaehlten Spieler
	 */
	private void deactivatePlayer() {
		int playerIndex = view.getSelectedPlayerIndex();
		if (playerIndex != -1) {
		Player player = getTableModel().getPlayerAt(playerIndex);
		player.setActive(false);
		db.store(player);
		// Loeschen der alten Textfeldinhalte
		view.refresh();
		System.out.println("Player stored");
		// Benachrichtigen des MainControllers
		this.setChanged();
		this.notifyObservers();
		getTableModel().fireTableChanged(new TableModelEvent(getTableModel()));
		} else {
			System.err.println("No Player selected!");
			JOptionPane.showMessageDialog(view,
				    "Sie haben keinen Spieler ausgewählt!",
				    "Fehler",
				    JOptionPane.ERROR_MESSAGE);
		}
	}
	
	/**
	 * schaltet den deactiviert-Filter um
	 */
	private void toggleFilter() {
		view.toogleFilter();
	}
	
	/**
	 * l�d den in der Tabelle ausgewaehlten Spieler in das Formular
	 */
	private void loadPlayer() {
		int playerIndex = view.getSelectedPlayerIndex();
		if (playerIndex != -1) {
		Player player =getTableModel().getPlayerAt(playerIndex);
		DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM,
				Locale.GERMANY);
		
		view.setFirstNameText(player.getFirstName());
		view.setFamilyNameText(player.getFamilyName());
		view.setPlaysSinceText(String.valueOf(player.getPlaysSince()));
		view.setDobText(df.format(player.getDateOfBirth()));
		} else {
			System.err.println("No player selected!");
			JOptionPane.showMessageDialog(view,
				    "Sie haben keinen Spieler ausgewählt!",
				    "Fehler",
				    JOptionPane.ERROR_MESSAGE);
		}
	}
	
	/**
	 * Versucht einen neuen Spieler in der Datenbank abzuspeichern
	 * Daten werden aus dem InputModel uebernommen
	 */
	private void addPlayer() {
		/**
		 * Uebertragen der Werte aus den Eingabefeldern in das PlayerModel
		 */
		inputModel.setFirstName(view.getFirstNameText());
		inputModel.setFamilyName(view.getFamilyNameText());
		inputModel.setPlaysSince(view.getPlaysSinceText());
		inputModel.setDateOfBirth(view.getDobText());
		
		
		boolean check = true;
		Player player = null;
		
		// Model fragen, ob alles valide ist
		if (inputModel.isModelValid() == false) {
			check = false;
			JOptionPane.showMessageDialog(view,
				    "Eingabe ist noch fehlerhaft.",
				    "Fehler",
				    JOptionPane.ERROR_MESSAGE);
 
		} else {
            player=new Player(inputModel.getFirstName(),
            		          inputModel.getFamilyName(),
            		          inputModel.getPlaysSince(),
            		          inputModel.getDateOfBirth());
            
		}
		if(getTableModel().contains(player)){
			check = false;
			JOptionPane.showMessageDialog(view,
				    "Der Spieler ist bereits vorhanden",
				    "Fehler",
				    JOptionPane.ERROR_MESSAGE);
		}
		
		// Wenn das Model valide ist, dann wird der neue Player
		// in die Datenbank aufgenommen
		if (check == true) {
			player.setPlaysSince(inputModel.getPlaysSince());
			getTableModel().addPlayer(player);
			// Speichern des Spielers
			db.store(player);
			// Loeschen der alten Textfeldinhalte
			view.refresh();
			System.out.println("Player stored");
			// Benachrichtigen des MainControllers
			this.setChanged();
			this.notifyObservers();
		} else {
			System.err.println("Sorry, there was a problem with the input "
					           +  "data.");
		}
	}

	/**
	 * View zurueckliefern
	 * @see dialogs.ChildController#getView()
	 */
	public PlayerView getView() {
		return view;
	}

	
	/**
	 * Daten aus der Datenbank neu einlesen
	 * @see dialogs.ChildController#updateFromDatabase()
	 */
	public void updateFromDatabase() {
        ObjectSet<Player> result = db.queryByExample(Player.class);
		
		for (Player player : result) {	
			if(! getTableModel().contains(player)) {
				// Spieler zu Model hinzufuegen, falls er noch nicht vorhanden
				// ist
				getTableModel().addPlayer(player);
			}
		}
	}

	public PlayerTableModel getTableModel() {
		return tableModel;
	}

	public void setTableModel(PlayerTableModel tableModel) {
		this.tableModel = tableModel;
	}
}
